#ifndef GAMEOBJECT_H_
#define GAMEOBJECT_H_

#include <set>
#include <string>
#include "Box2D/Box2D.h"
#include "SFML/Graphics.hpp"
#include <SFML/OpenGL.hpp>
#include "GameState.h"

using namespace std;

class GameObject
{
public:
	GameObject(GameState *gameState);

	~GameObject();

	// Id handling
	unsigned int getId() const { return m_id; }

	void setId(unsigned int id) { m_id = id; }

	// Properties
	bool hasProperty(const string &name) const;

	void addProperty(const string &name);

	void deleteProperty(const string &name);

	// GameState
	void setGameState(GameState *state) { m_gameState = state; }

	// Update
	virtual void update(double dt) { return; }

	virtual void firstUpdate() { return; }

	bool isFirstUpdate() { return m_firstUpdate; }
	
	void setFirstUpdate(bool value) { m_firstUpdate = value;}

	// Transformations
	virtual const b2Vec2& getPosition() const;

	virtual void setPosition(const b2Vec2 &position);

	virtual float getRotation() const;

	virtual void setRotation(float radians);

	virtual const b2Vec2& getSize() const;

	virtual void setSize(const b2Vec2 &size);

	// State
	bool isAlive(){ return m_alive; }

	void kill() { m_alive = false; }

	// Rendering
	bool isVisible(){ return m_visible; }

	void setVisible(bool visible){ m_visible = visible; }

	sf::Texture* getTexture();

	void setTexture(sf::Texture &texture); // By passing as a reference we avoid null pointers

	const float* getColor() const;

	void setColor(float r, float g, float b, float a = 1.0f);

	virtual void draw();

protected:
	
	GameState *m_gameState;

	b2Vec2 m_position;

	float m_rotation; // radians

	b2Vec2 m_size;

	bool m_alive;

	bool m_visible;

	sf::Texture *m_texture;

	float m_color[4];

	bool m_firstUpdate;

private:

	unsigned int m_id;

	set<string> m_properties;
	
};

#endif
